﻿namespace Yewan.Modbus
{
    public abstract class BaseModbus
    {
        /// <summary>
        /// 连接
        /// </summary>
        public virtual void Connect() { }

        /// <summary>
        /// 断开连接
        /// </summary>
        public virtual void Disconnect() { }

        /// <summary>
        /// 读取
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="code">功能码</param>
        /// <param name="startAddress">线圈起始地址</param>
        /// <param name="count">线圈数量</param>
        /// <returns></returns>
        public virtual byte[] Read(byte slave, FunctionCode code, ushort startAddress, ushort count) => null!;

        /// <summary>
        /// 异步读取
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="func"></param>
        /// <param name="startAddress"></param>
        /// <param name="count"></param>
        /// <param name="handler"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public virtual Task ReadAsync(byte slave, FunctionCode func, ushort startAddress, ushort count, int handler, Action<byte[], int, Exception> callback) => Task.CompletedTask;

        /// <summary>
        /// 写入单个线圈
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="code">功能码</param>
        /// <param name="address">寄存器地址</param>
        /// <param name="value">布尔值</param>
        /// <returns></returns>
        public virtual byte[] Write(byte slave, FunctionCode code, ushort address, bool value) => null!;

        /// <summary>
        /// 写入单个寄存器
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="code">功能码</param>
        /// <param name="address">寄存器地址</param>
        /// <param name="value">数据值</param>
        /// <returns></returns>
        public virtual byte[] Write(byte slave, FunctionCode code, ushort address, ushort value) => null!;

        /// <summary>
        /// 写入多个线圈
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="code">功能码</param>
        /// <param name="startAddress">寄存器地址</param>
        /// <param name="values">数据值</param>
        /// <returns></returns>
        public virtual byte[] Write(byte slave, FunctionCode code, ushort startAddress, bool[] values) => null!;

        /// <summary>
        /// 写入多个寄存器
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="code">功能码</param>
        /// <param name="startAddress">寄存器地址</param>
        /// <param name="values">数据值</param>
        /// <returns></returns>
        public virtual byte[] Write(byte slave, FunctionCode code, ushort startAddress, ushort[] values) => null!;

        /// <summary>
        /// 发送并接收
        /// </summary>
        /// <param name="data">发送的字节数据</param>
        /// <param name="receiveLength">接收的字节长度</param>
        /// <returns></returns>
        protected virtual byte[] SendAndReceive(byte[] data, int receiveLength) => null!;

        /// <summary>
        /// 构建请求头
        /// </summary>
        public static void BuildHeader(Span<byte> buffer, byte slave, FunctionCode code, ushort address, ushort value, byte? byteCount = null)
        {
            buffer[0] = slave;
            buffer[1] = (byte)code;
            buffer[2] = (byte)(address >> 8);
            buffer[3] = (byte)(address & 0xFF);
            buffer[4] = (byte)(value >> 8);
            buffer[5] = (byte)(value & 0xFF);

            if (byteCount.HasValue)
                buffer[6] = byteCount.Value;
        }

    }
}
